﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Packaging;
using System.Windows.Xps.Packaging;
using System.Windows.Documents;
using System.IO;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Drawing;
using System.Threading;

namespace SPThumbnailExtender.Interne
{
    internal class ThumbnailXPS : ThumbnailBase
    {
        private int iCount;
        public ThumbnailXPS(Uri uri)
            : base(uri)
        {
            this.Width = 420;
            this.Height = 594;
        }
        public ThumbnailXPS(Uri uri, int Width, int Height)
            : base(uri, Width, Height)
        { }
        public override System.Drawing.Bitmap GenerateThumbnail()
        {
            return GenerateThumbnail(0);
        }

        public override System.Drawing.Bitmap GenerateThumbnail(int Page)
        {
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(this.FileUri.AbsoluteUri);

            using (Package package = Package.Open(this.GetFileStream()))
            {
                Uri packageUri = new Uri("memorystream://" + fileNameWithoutExtension + "count.xps");
                if (PackageStore.GetPackage(packageUri) == null)
                    PackageStore.AddPackage(packageUri, package);
                XpsDocument doc = new XpsDocument(package, CompressionOption.Maximum, packageUri.AbsoluteUri);

                FixedDocumentSequence docPageSeq = doc.GetFixedDocumentSequence();

                string fileExtension = string.Empty;
                BitmapEncoder bitmapEncoder = null;

                fileExtension = ".jpg";
                bitmapEncoder = new JpegBitmapEncoder();

                DocumentPage documentPage = docPageSeq.DocumentPaginator.GetPage(Page);
                System.Windows.Size MaxSize = new System.Windows.Size(Width, Height);


                RenderTargetBitmap targetBitmap = new RenderTargetBitmap((int)MaxSize.Width, (int)MaxSize.Height,
                  96.0 * MaxSize.Width / documentPage.Size.Width, 96.0 * MaxSize.Height / documentPage.Size.Height,
                  PixelFormats.Pbgra32);
                targetBitmap.Render(documentPage.Visual);

                bitmapEncoder.Frames.Add(BitmapFrame.Create(targetBitmap));

                MemoryStream memoryStream = new MemoryStream();
                

                    bitmapEncoder.Save(memoryStream);
                    Bitmap bmp = (Bitmap)Bitmap.FromStream(memoryStream);
                        Helper.DeleteThumbnail(this.FileUri, Page);
                        Helper.InsertThumbnail(this.FileUri, Page, bmp);
                
                PackageStore.RemovePackage(packageUri);
                doc.Close();
                return bmp;
            }


        }

        public override void GenerateThumbnails()
        {
            ThreadStart ts = new ThreadStart(this.DoWorkGenerateThumbnails);
            Thread t = new Thread(ts);
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
            t.Join();

        }

        private void DoWorkGenerateThumbnails()
        {

            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(this.FileUri.AbsoluteUri);

            using (Package package = Package.Open(this.GetFileStream()))
            {
                Uri packageUri = new Uri("memorystream://" + fileNameWithoutExtension + "count.xps");
                if (PackageStore.GetPackage(packageUri) == null)
                    PackageStore.AddPackage(packageUri, package);
                XpsDocument doc = new XpsDocument(package, CompressionOption.Maximum, packageUri.AbsoluteUri);

                FixedDocumentSequence docPageSeq = doc.GetFixedDocumentSequence();

                string fileExtension = string.Empty;

                fileExtension = ".png";

                int iPageCount = docPageSeq.DocumentPaginator.PageCount;
                Helper.DeleteThumbnailsForDocument(this.FileUri);
                object o = Helper.GetParameter("SPThumbnailExtender.NbPage");
                int iNBPage;
                if (o == null)
                    iNBPage = 0;
                else
                    int.TryParse(o.ToString(), out iNBPage);

                for (int miind = 0; miind < iPageCount; miind++)
                {
                    if (iNBPage > 0 && miind > iNBPage)
                    {
                        break;
                    }
                    BitmapEncoder bitmapEncoder = null;
                    bitmapEncoder = new PngBitmapEncoder();
                    DocumentPage documentPage = docPageSeq.DocumentPaginator.GetPage(miind);
                    System.Windows.Size MaxSize = new System.Windows.Size(Width, Height);

                    RenderTargetBitmap targetBitmap = new RenderTargetBitmap((int)MaxSize.Width, (int)MaxSize.Height,
                      96.0 * MaxSize.Width / documentPage.Size.Width, 96.0 * MaxSize.Height / documentPage.Size.Height,
                      PixelFormats.Pbgra32);
                    targetBitmap.Render(documentPage.Visual);

                    bitmapEncoder.Frames.Add(BitmapFrame.Create(targetBitmap));

                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        bitmapEncoder.Save(memoryStream);
                        using (Bitmap bmp = (Bitmap)Bitmap.FromStream(memoryStream))
                        {
                            Helper.InsertThumbnail(this.FileUri, miind, bmp);
                        }
                    }
                }
                PackageStore.RemovePackage(packageUri);
                doc.Close();
            }
        }
        public override int GetCount()
        {
            Object o=new object();
            ThreadStart ts = new ThreadStart(this.DoWorkGetCounts);
            Thread t = new Thread(ts);
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
            t.Join();
            return iCount;
        }
        private void DoWorkGetCounts()
        {
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(this.FileUri.AbsoluteUri);

            using (Package package = Package.Open(this.GetFileStream()))
            {
                Uri packageUri = new Uri("memorystream://" + fileNameWithoutExtension + "count.xps");
                if (PackageStore.GetPackage(packageUri) == null)
                    PackageStore.AddPackage(packageUri, package);
                XpsDocument doc = new XpsDocument(package, CompressionOption.Maximum, packageUri.AbsoluteUri);

                FixedDocumentSequence docPageSeq = doc.GetFixedDocumentSequence();

                int iPageCount = docPageSeq.DocumentPaginator.PageCount;
                PackageStore.RemovePackage(packageUri);
                doc.Close();
                iCount = iPageCount;
            }
        }
    }
}

